﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.IO;
using memo;
using System.ComponentModel;

namespace memoVM
{
    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private static bool Mock;

        public static ViewModel Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ViewModel(Mock);
                }
                return instance;
            }
        }
        #region Property
        public int SelectedTopic
        {
            get
            {
                return selectedTopic;
            }

            set
            {
                selectedTopic = value;
            }
        }

        public int SelectedSubtopic
        {
            get
            {
                return selectedSubtopic;
            }

            set
            {
                selectedSubtopic = value;
            }
        }

        public int SelectedContent
        {
            get
            {
                return selectedContent;
            }

            set
            {
                selectedContent = value;
            }
        }

        public int SelectedTest
        {
            get { return selectedTest; }
            set { selectedTest = value; }
        }
        #endregion

        private ViewModel() { }

        public ViewModel(bool mock)
        {
            Mock = mock;
            Environment.SetEnvironmentVariable("DataAccessorTestMode", mock.ToString());
            _DataAccessor = DataAccessorFactory.Get();
            LoadData();
        }

        private void LoadData()
        {
            myTopics = _DataAccessor.Load();
        }

        private void SaveData()
        {
            _DataAccessor.Save(myTopics);
        }

        public int GetNumberOfTopics()
        {
            int numberOfTopic = 0;
            if (myTopics != null)
            {
                numberOfTopic = myTopics.Count;
            }
            return numberOfTopic;
        }

        public Topic GetTopicAtIndex(int index)
        {
            return myTopics[index];
        }

        public int GetNumberOfSubtopics()
        {
            int numberOfSubtopic = 0;
            if (myTopics[selectedTopic].SubTopics != null)
            {
                numberOfSubtopic = myTopics[selectedTopic].SubTopics.Count;
            }
            return numberOfSubtopic;
        }

        public SubTopic GetSubtopicAtIndex(int index)
        {
            return myTopics[selectedTopic].SubTopics[index];
        }

        public int GetNumberOfContents()
        {
            int numberOfContents = 0;
            if (myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents != null)
            {
                numberOfContents = myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents.Count;
            }
            return numberOfContents;
        }

        public Content GetContentAtIndex(int index)
        {
            return myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents[index];
        }

        public Topic GetSelectedTopic()
        {
            return myTopics[selectedTopic];
        }

        public bool SelectedContentsIsNotEmpty()
        {
            if (myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents == null)
            {
                return false;
            }
            else
            {
                if (myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents.Count == 0)
                {
                    return false;
                }
            }
            return true;
        }

        public SubTopic GetSelectedSubtopic()
        {
            return myTopics[selectedTopic].SubTopics[selectedSubtopic];
        }

        public Content GetSelectedContent()
        {
            return myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents[selectedContent];
        }

        public string GetTopicAndSubtopicName()
        {
            return myTopics[selectedTopic].Title + " - " + myTopics[selectedTopic].SubTopics[selectedSubtopic].Title;
        }

        public bool SetNextContent()
        {
            bool increasable = false;
            if (myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents.Count-1 > selectedContent)
            {
                selectedContent++;
                increasable = true;
            }
            return increasable;
        }

        public bool SetPreviousContent()
        {
            bool decreasable = false;
            if (0 < selectedContent)
            {
                selectedContent--;
                decreasable = true;
            }
            return decreasable;
        }

        public bool DeleteSelectedContent()
        {
            bool removeSuccessful = true;
            try
            {

                myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents.RemoveAt(selectedContent);
            }
            catch (Exception)
            {

                removeSuccessful = false;
            }
            return removeSuccessful;
        }

        public void SaveTopic(string topicName, string description, string icon)
        {
            myTopics.Add(new Topic(topicName, description, new List<SubTopic>(), icon));
        }

        public void EditTopic(string topicname, string description, string icon)
        {
            myTopics[selectedTopic].Title = topicname;
            myTopics[selectedTopic].ShortDescription = description;
            myTopics[selectedTopic].Icon = icon;
        }

        public bool DeleteSelectedTopic()
        {
            bool removeSuccessful = true;
            try
            {
                myTopics.RemoveAt(selectedTopic);
            }
            catch (Exception)
            {
                removeSuccessful = false;
            }
            return removeSuccessful;
        }

        public void SaveSubtopic(string title, string description, string icon)
        {
            if (myTopics[selectedTopic].SubTopics != null)
            {
                myTopics[selectedTopic].SubTopics.Add(new SubTopic(title, description, null, icon));
            }
            else
            {
                myTopics[selectedTopic].SubTopics = new List<SubTopic>();
                myTopics[selectedTopic].SubTopics.Add(new SubTopic(title, description, null, icon));
            }
        }

        public void EditSubtopic(string title, string description, string icon)
        {
            myTopics[selectedTopic].SubTopics[selectedSubtopic].Title = title;
            myTopics[selectedTopic].SubTopics[selectedSubtopic].ShortDescription = description;
            myTopics[selectedTopic].SubTopics[selectedSubtopic].Icon = icon;
        }

        public bool DeleteSelectedSubtopic()
        {
            bool removeSuccessful = true;
            try
            {
                myTopics[selectedTopic].SubTopics.RemoveAt(selectedSubtopic);
            }
            catch (Exception)
            {
                removeSuccessful = false;
            }
            return removeSuccessful;
        }

        public void SaveContent(string title, string detail)
        {
            if (myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents != null)
            {
                myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents.Add(new Content(title, detail));
            }
            else
            {
                myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents = new List<Content>();
                myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents.Add(new Content(title, detail));
            }
            
        }

        public void EditContent(string title, string detail)
        {
            myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents[selectedContent].Title = title;
            myTopics[selectedTopic].SubTopics[selectedSubtopic].Contents[selectedContent].Details = detail;
        }

        public void Exit()
        {
            SaveData();
        }

        public bool AddImageToContent(string image)
        {
            bool result = false;
            try
            {
                myTopics[selectedTopic].SubTopics[SelectedSubtopic].Contents[selectedContent].AddImage(image);
                result = true;
            }
            catch (Exception)
            {
                result = false;   
            }

            return result;
        }

        public int GetNumberOfTests()
        {
            int numberOfTests;
            try
            {
                numberOfTests = myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests.Count;
            }
            catch (NullReferenceException)
            {
                myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests = new List<Test>();
                numberOfTests = myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests.Count;
            }

            return numberOfTests;                
        }

        public Test GetFirstTest()
        {
            Test myTest;
            try
            {
                myTest = myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests[0];
                selectedTest = 0;
            }
            catch (NullReferenceException)
            {
                myTest = new Test();
            }

            return myTest;
        }

        public Test GetNextTest()
        {
            Test myTest;
            if (selectedTest < myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests.Count - 1)
            {
                selectedTest++;
                myTest = myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests[selectedTest];
            }
            else
            {
                myTest = GetFirstTest();
            }

            return myTest;
        }

        public Test GetSelectedTest()
        {
            return myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests[selectedTest];
        }

        public Test GetNewDefaultTest()
        {
            return new Test();
        }

        public bool EditTest(Test test)
        {
            bool isSuccessful = true;
            try
            {
                myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests[selectedTest] = test;
            }
            catch (Exception)
            {
                isSuccessful = false;
            }

            return isSuccessful;
        }

        public bool SaveTest(Test test)
        {
            bool isSuccessful = true;
            try
            {
                myTopics[selectedTopic].SubTopics[selectedSubtopic].Tests.Add(test);
            }
            catch (Exception)
            {
                isSuccessful = false;
            }

            return isSuccessful;
        }

        private IDataAccessor _DataAccessor;
        private List<Topic> myTopics;
        private static ViewModel instance;
        private int selectedTopic;
        private int selectedSubtopic;
        private int selectedContent;
        private int selectedTest;
    }
}